package com.system.coupon.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.system.common.interceptor.LoginInterceptor;
import com.system.common.model.LoginUser;
import com.system.common.resp.CommonResp;
import com.system.common.resp.PageResp;
import com.system.common.utils.CommonUtil;
import com.system.coupon.enums.BizCodeEnum;
import com.system.coupon.enums.CouponCategoryEnum;
import com.system.coupon.enums.CouponPublishEnum;
import com.system.coupon.enums.CouponStateEnum;
import com.system.coupon.exception.BizException;
import com.system.coupon.mapper.CouponMapper;
import com.system.coupon.mapper.CouponRecordMapper;
import com.system.coupon.model.CouponDO;
import com.system.coupon.model.CouponRecordDO;
import com.system.coupon.req.CouponQueryReq;
import com.system.coupon.service.CouponService;
import com.system.coupon.vo.CouponVO;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 小滴课堂,愿景：让技术不再难学
 *
 * @Description
 * @Author 二当家小D
 * @Remark 有问题直接联系我，源码-笔记-技术交流群
 * @Version 1.0
 **/

@Service
@Slf4j
public class CouponServiceImpl implements CouponService {



    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private CouponMapper couponMapper;


    @Autowired
    private CouponRecordMapper couponRecordMapper;


    @Override
   // @Cacheable(value = {"coupon"},key = "#root.methodName + #req.page+'_'+#req.size")
    public PageResp<CouponVO> pageCouponActivity(CouponQueryReq req) {

        Page<CouponDO> pageCondition = new Page<>(req.getPage(), req.getSize());

        IPage<CouponDO> couponDOIPage =  couponMapper.selectPage(pageCondition, new QueryWrapper<CouponDO>()
            .eq("publish", CouponPublishEnum.PUBLISH)
            .eq("category", CouponCategoryEnum.PROMOTION)
            .orderByDesc("create_time"));
        System.out.println("couponDOIPage: "+couponDOIPage);
        List<CouponVO> list = BeanUtil.copyToList(couponDOIPage.getRecords(), CouponVO.class);
        PageResp<CouponVO> pageResp = new PageResp<>();
        pageResp.setTotal(couponDOIPage.getTotal());
        pageResp.setList(list);
        return pageResp;
    }

    @Override
    public void addCoupon(long couponId, CouponCategoryEnum category) {
        CouponDO couponDO = couponMapper.selectOne(new QueryWrapper<CouponDO>()
                .eq("id", couponId)
                .eq("category", category.name()));
        LoginUser loginUser = LoginInterceptor.threadLocal.get();
        //优惠券是否可以领取
        this.checkCoupon(couponDO, 3l);

        //构建领劵记录
        CouponRecordDO couponRecordDO = new CouponRecordDO();
        BeanUtils.copyProperties(couponDO, couponRecordDO);
        couponRecordDO.setCreateTime(new Date());
        couponRecordDO.setUseState(CouponStateEnum.NEW.name());
        couponRecordDO.setUserId(loginUser.getId());
        couponRecordDO.setUserName(loginUser.getUsername());
        couponRecordDO.setCouponId(couponId);
        couponRecordDO.setId(null);

        //扣减库存
        int rows = couponMapper.reduceStock(couponId);

        //int flag = 1/0;

        if (rows == 1) {
            //库存扣减成功才保存记录
            couponRecordMapper.insert(couponRecordDO);

        } else {
            log.warn("发放优惠券失败:{},用户:{}", couponDO,"");
            throw new BizException(BizCodeEnum.COUPON_NO_STOCK);
        }
    }

    private CouponVO beanProcess(CouponDO couponDO) {
        CouponVO couponVO = new CouponVO();
        BeanUtils.copyProperties(couponDO,couponVO);
        return couponVO;
    }
    /**
     * 校验是否可以领取
     * @param couponDO
     * @param
     */
    private void checkCoupon(CouponDO couponDO, Long userId) {

        if (couponDO == null) {
            throw new BizException(BizCodeEnum.COUPON_NO_EXITS);
        }

        //库存是否足够
        if (couponDO.getStock() <= 0) {
            throw new BizException(BizCodeEnum.COUPON_NO_STOCK);
        }

        //判断是否是否发布状态
        if (!couponDO.getPublish().equals(CouponPublishEnum.PUBLISH.name())) {
            throw new BizException(BizCodeEnum.COUPON_GET_FAIL);
        }

        //是否在领取时间范围
        long time = CommonUtil.getCurrentTimestamp();
        long start = couponDO.getStartTime().getTime();
        long end = couponDO.getEndTime().getTime();
        if (time < start || time > end) {
            throw new BizException(BizCodeEnum.COUPON_OUT_OF_TIME);
        }

        //用户是否超过限制
        long recordNum = couponRecordMapper.selectCount(new QueryWrapper<CouponRecordDO>()
                .eq("coupon_id", couponDO.getId())
                .eq("user_id", userId));

        if (recordNum >= couponDO.getUserLimit()) {
            throw new BizException(BizCodeEnum.COUPON_OUT_OF_LIMIT);
        }
    }
}
